package com.example.lin.interceptor;

import cn.hutool.core.util.StrUtil;
import com.example.lin.entity.vo.LoginUser;
import com.example.lin.exception.GlobalException;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;

/**
 * token拦截器
 *
 * @author Administrator
 */
@Slf4j
@Component
public class TokenInterceptor implements HandlerInterceptor {

    @Resource
    private RedisTemplate<String, Object> redisTemplate;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String uri = request.getRequestURI();
        log.info("请求的uri为：{}", uri);
        if (StrUtil.equals("/api/login", uri)) {
            return true;
        }
        LoginUser user = (LoginUser) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        log.info("用户名:{}", user.getUsername());
        String token = request.getHeader("Authorization");
        if (StrUtil.isBlank(token)) {
            throw new GlobalException("请求的token为空");
        }
        log.info("传递的token为：{}", token);
        try {
            String redisToken = (String) redisTemplate.opsForValue().get("username:" + user.getUsername());
            if (StrUtil.isBlank(token)) {
                throw new GlobalException("token已过期！");
            }
            if (!StrUtil.equals(token, redisToken)) {
                throw new GlobalException("token不一致！");
            }
            return true;
        } catch (GlobalException e) {
            response.setContentType("application/json;charset=UTF-8");
            response.getWriter().write(e.getMessage());
            response.setStatus(401);
            response.getOutputStream().flush();
            response.getOutputStream().close();
            return false;
        }
    }
}
